package synchronicity.host;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import javax.bluetooth.ServiceRecord;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;

import synchronicity.agent.Agent;
import synchronicity.agent.AgentFactory;
import synchronicity.calendar.Calendar;
import synchronicity.calendar.Calendar.ModifyCalendarFailedException;
import synchronicity.util.Range;
import synchronicity.util.RangeSet;

/**
 * A stub for a remote SchedulerHost. The only working methods are traverse() and
 * getHostIdentifier()
 */
public class SchedulerHostStub implements SchedulerHost {

	private ServiceRecord record;

	public SchedulerHostStub(ServiceRecord record) {
		this.record = record;
	}

	public RangeSet getBusyTimes(Range range) {
		throw new RuntimeException("SchedulerHostStub does not support getBusyTimes()");
	}

	public SchedulerHost[] getHostsReachableFromHere() {
		throw new RuntimeException("SchedulerHostStub does not support getHostsReachableFromHere()");
	}
	
	public void addMeeting(Range range, String title) throws ModifyCalendarFailedException {
		throw new RuntimeException("SchedulerHostStub does not support addMeeting()");
	}
	
	public void addMeetingSchedulerListener(MeetingSchedulerListener listener) {
		throw new RuntimeException("SchedulerHostStub does not support addMeetingSchedulerListener()");
	}
	public void removeMeetingSchedulerListener(MeetingSchedulerListener listener) {
		throw new RuntimeException("SchedulerHostStub does not support removeMeetingSchedulerListener()");
	}
	public Calendar getCalendar() {
		throw new RuntimeException("SchedulerHostStub does not support getCalendar()");
	}

	public Agent traverse(Agent agent) {
		try {
			String url = record.getConnectionURL(
					ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
			System.out.println("Accesing remote device on "+url);
			StreamConnection remote = (StreamConnection) Connector.open(url);
			DataOutputStream out = remote.openDataOutputStream();
			DataInputStream in = remote.openDataInputStream();
			System.out.println("Writing agent "+ agent+ " " + System.currentTimeMillis());
			// Write the agent type so that the skeleton
			// can create the appropriate agent
			out.writeUTF(agent.getType());
			agent.write(out);
			out.flush();
			agent = AgentFactory.createNewAgent(agent.getType());
			System.out.println("Reading agent " + agent+ " " + System.currentTimeMillis());
			agent.read(in);
			System.out.println("Agent returned! " + agent+ " "+ System.currentTimeMillis() );
			in.close();
			out.close();
			remote.close();
			return agent;
		} catch (IOException ioe) {
			return agent;
		}
	}
	
	public String getHostIdentifier() {
		return record.getHostDevice().getBluetoothAddress();
	}
}
